package com.kin207.netty.relay.mq.listener;

import java.util.HashSet;
import java.util.Set;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import com.alibaba.fastjson.JSON;
import com.kin207.netty.context.RequestContext;
import com.kin207.netty.handle.IMessageHandle;
import com.kin207.netty.listener.ListenerConfig;
import com.kin207.netty.listener.MessageHandleListener;
import com.kin207.netty.spring.SpringUtils;

/**
 * mq消息转发监听
 * @author kin207
 *
 */
public class MQRelayMessageHandleListener implements MessageHandleListener {
	final static Logger logger = LoggerFactory.getLogger(MQRelayMessageHandleListener.class);
	
	private String relayQuauaName;
	
	private Set<String> messageHandleFilterNames;
	
	private String jmsTemplateName;
	
	private JmsTemplate jmsTemplate;
	
	private String messageType;

	public void initialize(ListenerConfig cfg) {
		//消息转发mq队列名称
		relayQuauaName = cfg.getParam("relayQuauaName");
		logger.info("init relayQuauaName:{}.", relayQuauaName);
		
		//消息处理过滤清单
		String messageHandleNamesStr = cfg.getParam("messageHandleFilterNames");
		if(messageHandleNamesStr!=null && !"".equals(messageHandleNamesStr.trim())){
			messageHandleFilterNames = new HashSet();
			String[] ss = messageHandleNamesStr.split(",");
			for(String item : ss){
				messageHandleFilterNames.add(item.trim());
				logger.info("add messageHandleFilterNames:{}", item);
			}
		}else{
			logger.info("messageHandleFilterNames is non.");
		}
		
		//jmsTemplate spring name
		String jmsTemplateNameStr = cfg.getParam("jmsTemplateName");
		if(jmsTemplateNameStr!=null && !"".equals(jmsTemplateNameStr.trim())){
			jmsTemplateName = jmsTemplateNameStr;
			logger.info("set jmsTemplateName:{}", jmsTemplateNameStr);
		}
		
		String messageTypeStr = cfg.getParam("messageType");
		if(messageTypeStr!=null && !"".equals(messageTypeStr.trim())){
			messageType = messageTypeStr;
			logger.info("set messageType:{}", messageTypeStr);
		}
		
		//初始化jmstemplate
		if(jmsTemplate==null){
			logger.info("jmsTemplate init,jmsTemplateName:{}", jmsTemplateName);
			jmsTemplate =  jmsTemplateName==null?SpringUtils.getBean(JmsTemplate.class):SpringUtils.getBean(jmsTemplateName, JmsTemplate.class);
		}
	}

	public void created(IMessageHandle t) {
		//判断是消息否是过滤清单的，如果过滤清单为空，则表示全部
		if(messageHandleFilterNames!=null && !messageHandleFilterNames.contains(t.name())){
			logger.debug("message filter, not send.");
			return;
		}
		
		RequestContext req = RequestContext.curr.get();
		final String msg = "json".equals(messageType)?toJson(t.name(), req.getParams()):req.getMessage();
		final String clientId = req.getSession().getId();
		final String serverId = req.getServer().getName();
		logger.debug("send relay mq messageType:{}, sid:{}, cid:{}, message:{}",messageType, serverId, clientId, msg);
		if(relayQuauaName.contains(",")){
			for(String rq :relayQuauaName.split(",")){
				jmsTemplate.send(rq, new MessageCreator() {
					public Message createMessage(javax.jms.Session session) throws JMSException {
						TextMessage textmsg = session.createTextMessage();
						textmsg.setText(msg);
						textmsg.setStringProperty("sid", serverId);
						textmsg.setStringProperty("cid", clientId);
						return textmsg;
					}
				});
			}
		}else{
		jmsTemplate.send(relayQuauaName, new MessageCreator() {
			public Message createMessage(javax.jms.Session session) throws JMSException {
				TextMessage textmsg = session.createTextMessage();
				textmsg.setText(msg);
				textmsg.setStringProperty("sid", serverId);
				textmsg.setStringProperty("cid", clientId);
				return textmsg;
			}
		});
		}
		logger.debug("sebd relay mq success.");
	}

	public void destroyed(IMessageHandle t) {
		
	}
	
	private static String toJson(String handleName, Object param){
		StringBuffer result = new StringBuffer();
		result.append("{\"handle\":\"").append(handleName).append("\",\"param\":");
		result.append(JSON.toJSONString(param));
		result.append("}");
		return result.toString();
	}

	

}
